import chartFactory from '../index';

const chart = {};

chart.create = chartFactory

chart.init = function (opt) {
  this.create(opt);

  this.xAxis = this.container.append('g').attr('class', 'axis x-axis');

  this.legend = this.svg.append('g').attr('class', 'legend')
    .attr('transform', `translate(10, 10)`)

  this.container.append('g').attr('class', 'group-bars');
  this.tooltip = d3.select(this.config.target + ` .tooltip`);

  // 最初开始默认展示第一层级的定向
  this.dataConfig = { mode: 'same-level', level: 1 };

}



chart.update = function (architecture, industries, dataConfig) {

  // 一是定向体系数据
  // 二是所选择的行业数据
  this.architecture = architecture || this.architecture;
  this.industries = industries || this.industries;

  if (this.architecture == null || this.industries == null)
    return;
  // 用于应对初始情况

  this.industryCategories = this.industries.map(item => item.name);

  this.tooltip.style('visibility', 'hidden');

  if (dataConfig != null) {
    this.dataConfig = Object.assign({}, this.dataConfig, dataConfig);
  }


  this.color = d3.scaleOrdinal(d3.schemeCategory10).domain(this.industryCategories);

  let updateLegends = this.legend.selectAll('g').data(this.industryCategories),
    enterLegends = updateLegends.enter(), exitLegends = updateLegends.exit();
  exitLegends.remove();

  let legends = enterLegends.append('g').attr('transform', (d, i) => `translate(0, ${i * 25})`);
  legends.append('rect').attr('width', 20).attr('height', 20).attr('fill', d => this.color(d))
  legends.append('text').text(d => d)
    .attr('x', 25)
    .attr('y', 17);


  let dataSample = this.process(this.architecture, this.industries, this.dataConfig);

  if (dataSample.length == 0)
    return void (666);

  // 每一次更新视图时需要重新计算宽高
  let parentContainer = document.querySelector(this.config.target);
  this.width = parentContainer.clientWidth - this.config.margin.left - this.config.margin.right;
  this.height = parentContainer.clientHeight - this.config.margin.top - this.config.margin.bottom;

  this.x = d3.scaleBand().domain(dataSample.map(data => data.name))
    .rangeRound([0, this.width]).padding(0.01)

  this.subX = d3.scaleBand().domain(this.industryCategories)
    .rangeRound([0, this.x.bandwidth()]).padding(0.1);

  this.y = d3.scaleLog().base(1.5).domain([0.5, d3.max(dataSample, d => {
    return d3.max(d.industries, item => +item.value);
  })]).rangeRound([this.height, 0]);

  this.xAxis.attr('transform', `translate(0, ${this.height})`).call(d3.axisBottom().scale(this.x)).selectAll('text')
    .style('text-anchor', 'end')
    .attr('dx', '-.8em')
    .attr('dy', '.15em')
    .attr('transform', 'rotate(-55)')

  let updateGroups = this.container.select('.group-bars').selectAll('.bar')
    .data(dataSample), enterGroups = updateGroups.enter(),
    exitGroups = updateGroups.exit();
  exitGroups.remove();


  let updateBars = enterGroups.append('g').classed('bar', true).merge(updateGroups)
    .attr('transform', d => `translate(${this.x(d.name)}, 0)`)
    .selectAll('rect').data(d => d.industries), enterBars = updateBars.enter(), exitBars = updateBars.exit();
  exitBars.remove();

  enterBars.append('rect').merge(updateBars)
    .attr('x', d => this.subX(d.industry))
    .attr('y', d => this.y(+d.value))
    .attr('height', d => this.height - this.y(+d.value))
    .attr('width', this.subX.bandwidth() - 2)
    .attr('fill', d => {
      return this.color(d.industry)
    }).on('mouseenter', (d) => {
      let tooptipStr = `行业: ${d.industry}<br/>
        使用频次: ${d.value}`;
      this.tooltip.html(tooptipStr);
      this.tooltip.style('visibility', 'visible');
    }).on('mouseleave', (d) => {
      this.tooltip.style('visibility', 'hidden');
    }).on('mousemove', (d) => {
      this.tooltip.style('left', d3.event.pageX + 10 + 'px');
      this.tooltip.style('top', d3.event.pageY + 10 + 'px');
    })
}

chart.process = function (architecture, industries, { mode, level }) {
  let result = [];
  for (let node of architecture) {
    if (mode === 'same-level') {
      if (+node.level === level) {
        // 找到某一层级的节点
        let sum = [];
        industries.forEach(industry => {
          let temp = industry.data.find(item => item.name === node.name);
          sum.push(Object.assign({}, { industry: industry.name, value: temp ? +temp.value : 0, direction: node.name }))
        })
        result.push(Object.assign({}, { name: node.name, industries: sum }));
      }
    } else if (mode === 'same-parent') {
      if (node.parent === payload) {
        let sum = [];
        industries.forEach(industry => {
          let temp = industry.data.find(item => item.name === node.name);
          sum.push(Object.assign({}, { industry: industry.name, value: temp ? +temp.value : 0, direction: node.name }))
        })
        result.push(Object.assign({}, { name: node.name, industries: sum }));
      }
    }
  }

  result = result.filter(item => {
    let count = d3.sum(item.industries, d => +d.value)
    if (count === 0) {
      return false;
    }
    return true;
  })

  return result;
}

export default chart;